<template>
  <div class="user-info">
    <h1 style="font-size: 23px;">个人信息</h1>
    <!-- 分割线 -->
    <el-divider></el-divider>

    <el-row :gutter="20">
      <!-- 左边 -->
      <el-col :span="5" :offset="2">
        <div class="avatar-part">
          <el-image fit="cover" style="width: 163px; height: 163px; border-radius: 80px" @dragstart.prevent
            :src="userInfo.user.picture ? img_url_pre(userInfo.user.picture) : getImgSrc()"
            :preview-src-list="[userInfo.user.picture ? img_url_pre(userInfo.user.picture) : getImgSrc()]" />
          <el-button link @click="dialogVisible = true">
            <el-icon>
              <Right />
            </el-icon>
            点此更改头像
          </el-button>
        </div>
      </el-col>

      <!-- 右边 -->
      <el-col :span="13" :offset="2">
        <div class="info-part">
          <h1 style="font-size: 18px; margin-bottom: 30px;">
            <font-awesome-icon :icon="['fas', 'user-pen']" />
            基本信息
          </h1>
          <!-- 用户信息表 -->
          <el-form ref="userInfoFormRef" :model="userInfo.user" label-width="90px" :rules="rules" status-icon>
            <el-form-item prop="role" label="用户类型：">
              <el-tag style="margin-left: 130px" size="large" v-if="userInfo.user.role === 0">
                管理员
              </el-tag>
              <el-tag type="success" style="margin-left: 130px" size="large" v-else-if="userInfo.user.role === 1">
                普通用户
              </el-tag>
              <el-tag type="warning" style="margin-left: 130px" size="large" v-else>
                商户
              </el-tag>
            </el-form-item>
            <el-form-item prop="userId" label="用户ID：">
              <el-input input-style="text-align: center;" :readonly="true" v-model="userInfo.user.userId">
                <template #append>
                  <el-button>
                    <el-icon style="width: 28px; font-size: 18px;">
                      <UserFilled />
                    </el-icon>
                  </el-button>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item prop="username" label="用户名：">
              <el-input input-style="text-align: center;" :readonly="editing[0] === 0" v-model="userInfo.user.username">
                <template #append>
                  <el-button v-if="editing[0] === 0" @click="activateEdit(0)">修改</el-button>
                  <el-button v-else @click="deactivateEdit(0)">确认</el-button>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item prop="phoneNumber" label="手机号：">
              <el-input input-style="text-align: center;" :readonly="editing[1] === 0"
                v-model="userInfo.user.phoneNumber">
                <template #append>
                  <el-button v-if="editing[1] === 0" @click="activateEdit(1)">修改</el-button>
                  <el-button v-else @click="deactivateEdit(1)">确认</el-button>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item label="身份证号：">
              <el-input input-style="text-align: center;" :readonly="true" v-model="userInfo.user.idCardNumber">
                <template #append>
                  <el-button>
                    <el-icon style="width: 28px; font-size: 18px;">
                      <UserFilled />
                    </el-icon>
                  </el-button>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item prop="email" label="邮箱：">
              <el-input input-style="text-align: center;" :readonly="editing[2] === 0" v-model="userInfo.user.email">
                <template #append>
                  <el-button v-if="editing[2] === 0" @click="activateEdit(2)">修改</el-button>
                  <el-button v-else @click="deactivateEdit(2)">确认</el-button>
                </template>
              </el-input>
            </el-form-item>
          </el-form>
          <h1 class="tip">
            <el-icon style="margin-right: 5px;">
              <InfoFilled />
            </el-icon>
            注意：修改后请及时保存，否则修改无法生效
          </h1>
          <div class="two-button">
            <el-button type="primary" @click="submitUserInfoForm">保存</el-button>
            <el-button class="r-btn" type="info" @click="resetUserInfo">重置</el-button>
          </div>

          <!-- 分割线 -->
          <el-divider></el-divider>

          <!-- 修改密码 -->
          <h1 style="font-size: 18px; margin-bottom: 30px;">
            <font-awesome-icon :icon="['fas', 'user-shield']" />
            修改密码
          </h1>
          <el-form ref="userPasswordFormRef" :model="editPasswordForm" label-width="125px" :rules="rulesOfPassword"
            status-icon>
            <el-form-item prop="oldPassword" label="请输入旧密码：">
              <el-input type="password" show-password input-style="text-align: center;"
                v-model="editPasswordForm.oldPassword"></el-input>
            </el-form-item>
            <el-form-item prop="newPassword" label="请输入新密码：">
              <el-input type="password" show-password input-style="text-align: center;"
                v-model="editPasswordForm.newPassword"></el-input>
            </el-form-item>
            <el-form-item prop="confirmPassword" label="请确认新密码：">
              <el-input type="password" show-password input-style="text-align: center;"
                v-model="editPasswordForm.confirmPassword"></el-input>
            </el-form-item>
          </el-form>
          <h1 class="tip">
            <el-icon style="margin-right: 5px;">
              <InfoFilled />
            </el-icon>
            注意：修改后请及时保存，否则修改无法生效
          </h1>
          <div class="two-button">
            <el-button type="primary" @click="submitPasswordForm">保存</el-button>
            <el-button class="r-btn" type="info" @click="resetPasswordForm(userPasswordFormRef)">重置</el-button>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>

  <el-dialog v-model="dialogVisible" title="更换头像" width="50%" class="my-dialog">
    <el-upload class="upload-board" action="#" multiple list-type="picture-card" :show-file-list="false" ref="upload"
      :on-change="handleChange" :limit="fileNumLimit" :on-exceed="handleExceed" :before-upload="beforeUpload"
      :auto-upload="false" :headers="headers">
      <img v-if="fileList.length" :src="fileList[0].url" class="upload-avatar" alt="上传的图片" />
      <el-icon v-else>
        <Plus />
      </el-icon>
    </el-upload>
    <div class="dialog-2-btn">
      <el-button type="primary" @click="uploadFile" :loading="upload_loading">确认</el-button>
      <el-button @click="clearFileList">重置</el-button>
    </div>
  </el-dialog>
</template>


<script setup>
import { onMounted, reactive, ref, getCurrentInstance } from 'vue'
import { useStore } from 'vuex'
import { phoneNumber, username, password1, password2 } from '../../../validator/index.js';
import img_url_pre from '../../../utils/img_url_filter';
import md5 from 'js-md5'  // 引入md5

const store = useStore()
const { proxy } = getCurrentInstance()

let editing = ref([0, 0, 0]);
const userInfoFormRef = ref();
const userPasswordFormRef = ref();
// 控制模态框的显示和隐藏
const dialogVisible = ref(false)

// 上传后的文件列表
let fileList = ref([])
// 允许的文件类型
let fileType = ["png", "jpg", "bmp", "jpeg", "gif", "webp"];
// 上传文件大小限制，单位MB
let fileSizeLimit = 10;
// 附件数量限制
let fileNumLimit = 1;
// 请求头
let headers = { "Content-Type": "multipart/form-data" };
const upload_loading = ref(false)

// 用户信息
const userInfo = reactive({
  user: {
    "userId": "",
    "username": "",
    "password": "",
    "phoneNumber": "",
    "idCardNumber": "",
    "email": "",
    "picture": "",
    "role": 1,
    "accountId": ""
  }
})

// 更改密码
const editPasswordForm = reactive({
  oldPassword: '',
  newPassword: '',
  confirmPassword: '',
})

// 用户信息校验规则
const rules = reactive({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 10, message: '长度应该在3~10个字符之间', trigger: 'blur' },
    { validator: username, trigger: 'blur' }
  ],
  phoneNumber: [
    { required: true, message: '请输入手机号码', trigger: 'blur' },
    { validator: phoneNumber, trigger: 'blur' },
  ],
  email: [
    { required: true, message: '请输入电子邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱', trigger: 'blur' },
  ],
})

const rulesOfPassword = reactive({
  oldPassword: [
    { required: true, message: '请输入旧密码', trigger: 'blur' },
    { min: 6, max: 32, message: '长度应该在6~32个字符之间', trigger: 'blur' },
    { validator: password1, trigger: 'blur' },
    { validator: password2, trigger: 'blur' },
  ],
  newPassword: [
    { required: true, message: '请输入新密码', trigger: 'blur' },
    { min: 6, max: 32, message: '长度应该在6~32个字符之间', trigger: 'blur' },
    { validator: password1, trigger: 'blur' },
    { validator: password2, trigger: 'blur' },
  ],
  confirmPassword: [
    { required: true, message: '请输入确认密码', trigger: 'blur' },
    {
      validator: function (rule, value, callback) {
        if (editPasswordForm.newPassword !== value) {
          callback(new Error("确认密码应和新密码一致"));
        } else {
          callback()
        }
      }, trigger: 'blur'
    },
  ],
})

// 获取用户信息
const getUser = async (userId) => {
  let res = await proxy.$api.user.getUser(userId)
  userInfo.user = res.data;
}

let getImgSrc = () => {
  return new URL("../../../assets/images/user_default.png", import.meta.url).href;
}

// 激活修改
const activateEdit = (index) => {
  editing.value[index] = 1;
}

// 取消激活修改
const deactivateEdit = async (index) => {
  let ret = await userInfoFormRef.value.validate();
  if (ret) {
    editing.value[index] = 0;
  }
}

// 重置表单（重新获取一下userInfo）
const resetUserInfo = async () => {
  await getUser(store.state.user.userId);
}

// 重置修改密码表单
const resetPasswordForm = (formEl) => {
  if (!formEl) return
  formEl.resetFields()
}

// 提交修改
const submitUserInfoForm = async () => {
  let valid = await userInfoFormRef.value.validate();
  if (valid) {
    for (let i = 0; i < editing.value.length; ++i)
      editing.value[i] = 0;
    let confirm = await ElMessageBox.confirm(
      '确定保存个人信息的更改吗？',
      '确认保存',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).catch(error => console.log(error));
    if (confirm === 'confirm') {
      let res = await proxy.$api.user.modifyUserInfo(userInfo.user).catch(error => {
        console.log(error)
        getUser(store.state.user.userId);
      });
      if (res.status === 200) {
        ElMessage.success({
          showClose: true,
          message: "成功更新用户信息"
        });
      }
    }
  }
}

// 提交修改密码
const submitPasswordForm = async () => {
  let valid = await userPasswordFormRef.value.validate();
  if (valid) {
    let confirm = await ElMessageBox.confirm(
      '更改后原密码将失效，确认更改密码吗？',
      '确认更改',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).catch(error => console.log(error));
    if (confirm === 'confirm') {
      let res = await proxy.$api.user.modifyUserPassword({
        userId: store.state.user.userId,
        oldPassword: md5(editPasswordForm.oldPassword),
        newPassword: md5(editPasswordForm.newPassword)
      }).catch(error => console.log(error));
      if (res.status === 200) {
        ElMessage.success({
          showClose: true,
          message: "成功更改密码"
        });
      }
    }
  }
}

// 超出文件个数的回调
const handleExceed = () => {
  ElMessage({
    showClose: true,
    type: 'warning',
    message: `超出最大上传文件数量${fileNumLimit}的限制，请先重置当前上传区`
  });
}

// 处理文件变动
const handleChange = (uploadFile, uploadFiles) => {
  fileList.value = uploadFiles;
}

// 上传文件之前
const beforeUpload = (file) => {
  if (file.type !== "" || file.type != null || file.type !== undefined) {
    // 截取文件的后缀，判断文件类型
    const FileExt = file.name.replace(/.+\./, "").toLowerCase();
    // 计算文件大小是否符合限制
    const isSizeAvail = (file.size / 1024 / 1024) < fileSizeLimit;
    // 如果大小超过限制
    if (!isSizeAvail) {
      this.$showMessage(`上传文件大小不能超过 ${fileSizeLimit}MB!`);
      return false;
    }
    // 如果文件类型不在允许上传的范围内
    if (fileType.includes(FileExt)) {
      return true;
    } else {
      ElMessage.error("上传文件格式不正确!");
      return false;
    }
  }
}

// 清除头像上传
const clearFileList = () => {
  fileList.value.splice(0, 1);
}

// 上传图片并更新相关的用户信息
const uploadFile = async () => {
  upload_loading.value = true;
  let formData = new FormData();  // 将文件封装进FormData
  fileList.value.forEach(file => {
    formData.append('files', file.raw)
  });
  // 调用上传接口
  let fileNames = await proxy.$api.img.uploadImg(formData).catch(error => {
    console.log(error);
    upload_loading.value = false;
  });
  userInfo.user.picture = fileNames.data[0];
  // 更新用户信息
  let ret = await proxy.$api.user.modifyUserInfo(userInfo.user).catch(error => {
    console.log(error);
    upload_loading.value = false;
  });
  if (ret.status === 200) {
    upload_loading.value = false;
    dialogVisible.value = false;
    ElMessage.success({
      showClose: true,
      message: "成功更换头像"
    })
  }
}

onMounted(async () => {
  await getUser(store.state.user.userId);
})
</script>


<style lang="less" scoped>
.user-info {
  background: linear-gradient(180deg, #ecf0f5ee 0%, #ffffffea 100%);
  padding: 30px;
  border-radius: 10px;

  /* 分割线 */

  .el-divider {
    border-top: 2px solid rgba(170, 165, 165, 0.651);
  }

  .avatar-part {
    display: flex;
    flex-direction: column;
    align-items: center;

    .el-button {
      margin-top: 12px;
      font-size: 18px;
    }
  }

  .info-part {
    .tip {
      display: flex;
      margin-top: 30px;
      color: #666666;
    }

    .two-button {
      display: flex;
      justify-content: center;
      margin-top: 30px;

      .r-btn {
        margin-left: 20px;
      }
    }
  }
}

.my-dialog {
  .upload-board {
    display: flex;
    justify-content: center;

    .upload-avatar {
      width: 100%;
      height: 100%;
      object-fit: cover;
      border-radius: 5px;
    }
  }

  .dialog-2-btn {
    display: flex;
    justify-content: center;
    margin-top: 50px;
  }
}
</style>